package com.liuyi.netty.im.server.util;

import cn.hutool.core.util.StrUtil;
import com.liuyi.netty.im.commons.codes.CodeConst;
import com.liuyi.netty.im.commons.codes.data.DataEvent;
import com.liuyi.netty.im.commons.codes.data.LimData;
import com.liuyi.netty.im.commons.codes.data.event.NotReady;
import com.liuyi.netty.im.commons.codes.unusual.LimException;
import com.liuyi.netty.im.commons.enums.UserLineStatus;
import com.liuyi.netty.im.commons.codes.LimProtocol;
import com.liuyi.netty.im.server.config.LimManage;
import com.liuyi.netty.im.server.handle.storage.ChannelStorage;
import com.liuyi.netty.im.server.handle.storage.User;
import io.netty.channel.Channel;

/**
 * Im 操作工具类
 *
 * @author Mr.Fmy
 * @since 2021-11-27
 */
public class ImHelp {

    /**
     * 顶替签名
     *
     * @param userId 用户id
     * @param device 设备
     */
    public static void replaced(String userId, String device) {
        //记录离线状态
        User user = LimManage.getUserStorage().offLine(userId, device);
        if (user != null) {
            //踢出
            LimManage.getRelationChainService().replaced(user.getSign());
            //事件通知
            ImUtil.sendCluster(CodeConst.Event.NOT_READY, CodeConst.EventToType.CHANNELID, user.getChannelId(), NotReady.REPLACED);
        }
    }

    /**
     * 注销签名
     */
    public static void logout(Channel channel) {
        User userinfo = ChannelStorage.getUserinfo(channel);
        if (userinfo != null && userinfo.getUserLineStatus().equals(UserLineStatus.ON)) {
            //执行退出
            LimManage.getRelationChainService().logout(userinfo.getSign());
            //标记为下线
            LimManage.getUserStorage().offLine(userinfo.getUserId(), userinfo.getDevice());
            //事件通知
            ImUtil.send(channel, new DataEvent(CodeConst.Event.NOT_READY, CodeConst.EventToType.CHANNELID, channel.id().asLongText(), NotReady.LOGOUT));
        }
    }

    /**
     * 得到json序列化格式的协议
     *
     * @param command 命令
     * @param content 内容
     * @return {@link LimProtocol}
     */
    public static <T extends LimData> LimProtocol getJsonProtocol(CodeConst.Command command, T content) {
        LimProtocol protocol = new LimProtocol();
        protocol.setVersion(CodeConst.MIN_VERSION);
        protocol.setCommand(command);
        protocol.setDataType(CodeConst.CONTENT_TYPE_JSON);
        protocol.setData(content);
        return protocol;
    }


    public static String getChannelIp(Channel channel) {
        return channel.remoteAddress().toString();
    }

    public static String sessionId(CodeConst.SessionType sessionType, String toId) {
        return sessionType.name() + "@" + toId;
    }

    public static CodeConst.SessionType sessionIdToType(String sessinId) {
        if (StrUtil.isNotEmpty(sessinId)) {
            String marking = sessinId.split("@")[0];
            if (StrUtil.isEmpty(marking)) {
                throw new LimException("sessionId Nonconformity to specification");
            }
            CodeConst.SessionType[] values = CodeConst.SessionType.values();
            for (CodeConst.SessionType value : values) {
                if (marking.equals(value.name())) {
                    return value;
                }
            }
        }
        throw new LimException("sessionId Nonconformity to specification");
    }

    public static String sessionIdToId(String sessinId) {
        if (StrUtil.isNotEmpty(sessinId)) {
            return sessinId.split("@")[1];
        }
        throw new LimException("sessionId Nonconformity to specification");
    }
}
